﻿using Microsoft.AspNetCore.Http;
using MyModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using SqlSugar.Extensions;
using System.IdentityModel.Tokens.Jwt;

namespace MyCommon.HttpContextUser
{
    public class AspNetUser : IUser
    {
        private readonly IHttpContextAccessor _accessor;
        private readonly ILogger<AspNetUser> _logger;

        public AspNetUser(IHttpContextAccessor accessor,ILogger<AspNetUser> logger)
        {
            _accessor = accessor;
            _logger = logger;
        }
        public string UserName => GetName();

        private string GetName()
        {
            if (IsAuthenticated() && !_accessor.HttpContext.User.Identity.Name.IsNullOrEmpty())
            {
                return _accessor.HttpContext.User.Identity.Name;
            }
            else
            {
                if (string.IsNullOrEmpty(GetToken()))
                {
                    var getNameType = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";
                    return GetUserInfoFromToken(getNameType).FirstOrDefault();
                }
            }
            return "";
        }

        public long UserId => Convert.ToInt64( GetClaimValueByType("jti").FirstOrDefault());

        public MessageModel<string> MessageModel { get ; set; }

        public IEnumerable<Claim> GetClaims()
        {
            if(_accessor.HttpContext==null) return ArraySegment<Claim>.Empty;

            if (!IsAuthenticated())
            {
                var jwtHandler = new JwtSecurityTokenHandler();
                var token = GetToken();
                if (!token.IsNullOrEmpty() && jwtHandler.CanReadToken(token))
                {
                    var jwtToken = jwtHandler.ReadJwtToken(token);
                    return jwtToken.Claims;
                }
            }

            var claims = _accessor.HttpContext.User.Claims.ToList();
            var headers =_accessor.HttpContext.Request.Headers;
            foreach (var header in headers)
            {
                claims.Add(new Claim(header.Key, header.Value));
            }
            return claims;
        }

        public List<string> GetClaimValueByType(string claimType)
        {
            var claims = GetClaims();
            return claims.Where(i=>i.Type == claimType).Select(i=>i.Value).ToList();
        }

        public string GetToken()
        {
            var token = _accessor.HttpContext?.Request?.Headers["Authorization"].ObjToString().Replace("Bearer", "");
            if(!token.IsNullOrEmpty())
            {
                return token;
            }
            return token;
        }

        public List<string> GetUserInfoFromToken(string claimType)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            var token = GetToken();
            if (!token.IsNullOrEmpty() && jwtHandler.CanReadToken(token))
            {
                var jwtToken = jwtHandler.ReadJwtToken(token);
                return jwtToken.Claims.Where(i=>i.Type==claimType).Select(i=> i.Value).ToList();
            }
            return new List<string> {  };
        }

        public bool IsAuthenticated()
        {
            return _accessor.HttpContext?.User?.Identity?.IsAuthenticated ?? false;
        }
    }
}
